﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net.Mail;
using System.Web;
using System.Web.WebPages.Html;
using DataLayer.Entities;
using DataLayer.Implementations;
using DonutMgmtSystemFoundation.Models;
using ViewRes;

namespace DonutMgmtSystemFoundation.Helpers
{
    public class LoginHelper
    {
        #region Metodos privados
        private bool IsValidEmail(string email)
        {
            try
            {
                var addr = new MailAddress(email);
                return true;
            }
            catch
            {
                return false;
            }
        }
        #endregion

        #region Login
        public GeneralJsonResultModel LoginUser(User user)
        {
            UserApplication userApp = new UserApplication();
            user.Password = EncryptionHelper.Encrypt(user.Password);
            User authenticatedUser = userApp.GetByUsernameAndPassword(user);
            if (authenticatedUser != null) // Si esta activo o es admin
            {
                if (!authenticatedUser.IsActive && authenticatedUser.Role.RoleId != 1)
                {
                    return new GeneralJsonResultModel(false, LoginStrings.MsgInactiveUser);
                }
                if (!authenticatedUser.ApprovedByAdmin)
                {
                    return new GeneralJsonResultModel(false, LoginStrings.MsgInactiveAdminUser);
                }
                SessionContext.SetAuthenticationToken(authenticatedUser.UserId.ToString(), false, authenticatedUser);
                return new GeneralJsonResultModel(true, "");
            }
            return new GeneralJsonResultModel(false, LoginStrings.MsgInvalidUserPass);
        }
        #endregion 

        #region Olvide mi password
        public GeneralJsonResultModel GenerateForgetPasswordRequest(string userOrEmail)
        {
            // Verificar si no esta vacio
            if (String.IsNullOrEmpty(userOrEmail))
            {
                return new GeneralJsonResultModel(false, LoginStrings.WriteUsernameEmail);
            }
            else
            {
                UserApplication userApp = new UserApplication();
                User user = IsValidEmail(userOrEmail) ? userApp.GetByEmail(userOrEmail) : userApp.GetByUsername(userOrEmail);
                if (user == null)
                {
                    return new GeneralJsonResultModel(false, LoginStrings.MsgNoUserTryAgain);
                }
                else
                {
                    try
                    {    
                        MailerHelper m = new MailerHelper();
                        string host = HttpContext.Current.Request.Url.Scheme + Uri.SchemeDelimiter + HttpContext.Current.Request.Url.Host + (HttpContext.Current.Request.Url.IsDefaultPort ? "" : ":" + HttpContext.Current.Request.Url.Port);
                        string activationKey = EncryptionHelper.Encrypt(user.Username + DateTime.Now.ToString());
                        string localUrl = String.Format("/Login/RecoverPassword/?Username={0}&ActivationKey={1}", user.Username, activationKey);
                        string actionLink = String.Format("{0}{1}", host, localUrl);

                        UserPassword u = new UserPassword()
                        {
                            IsActive = true,
                            PasswordApproval = activationKey,
                            User = user
                        };

                        UserPasswordApplication pApp = new UserPasswordApplication();
                        pApp.Save(u);

                        m.ForgetPassword(u, actionLink).Send();
                        return new GeneralJsonResultModel(true, String.Format(LoginStrings.MsgSuccsesMailSent, user.Email));
                    }
                    catch
                    {
                        return new GeneralJsonResultModel(false, LoginStrings.MsgErrorSendingMail);
                    }
                }
            }
        }

        public GeneralJsonResultModel RecoverPassword(ActivateUserModel model)
        {
            GeneralJsonResultModel result = new GeneralJsonResultModel();
            UserPasswordApplication userApp = new UserPasswordApplication();
            UserPassword user = userApp.GetByActivationKey(model.ActivationKey);
            if (user != null)
            {
                if (user.IsActive)
                {
                    if (user.PasswordApproval == model.ActivationKey)
                    {
                        return new GeneralJsonResultModel(true, "");
                    }
                }
            }
            return new GeneralJsonResultModel(false, LoginStrings.MsgErrorChangingPassword);
        }

        public GeneralJsonResultModel ChangePassword(string userName, string password)
        {
            UserApplication userApp = new UserApplication();
            User user = userApp.GetByUsername(userName);
            if (user != null)
            {
                UserPasswordApplication userPassApp = new UserPasswordApplication();
                UserPassword userPass = userPassApp.GetLastByUserId(user.UserId.Value);
                if (userPass != null)
                {
                    try
                    {
                        user.Password = EncryptionHelper.Encrypt(password);
                        userApp.Save(user);
                        userPass.IsActive = false;
                        userPassApp.Save(userPass);
                        return new GeneralJsonResultModel(true, LoginStrings.MsgPasswordChanged);
                    }
                    catch
                    {
                        return new GeneralJsonResultModel(false, LoginStrings.MsgErrorChangingPassword);
                    }
                }
            }
            return new GeneralJsonResultModel(false, LoginStrings.MsgUserInexistant);
        }
        #endregion

        #region Registrar usuario
        public GeneralJsonResultModel RegisterUser(User user)
        {
            if (String.IsNullOrEmpty(user.Name) || String.IsNullOrEmpty(user.Email)
                || String.IsNullOrEmpty(user.Username) || String.IsNullOrEmpty(user.Password))
            {
                return new GeneralJsonResultModel(false, LoginStrings.MissingFields);
            }
            if (!IsValidEmail(user.Email))
            {
                return new GeneralJsonResultModel(false, LoginStrings.WritePleaseEmail);
            }

            try
            {
                // Mandar correo y registrar usuario
                UserApplication app = new UserApplication();

                User duplicattedEmail = app.GetByEmail(user.Email);

                if (duplicattedEmail != null)
                {
                    return new GeneralJsonResultModel(false, LoginStrings.MsgErrorDupEmail);
                }

                User duplicatedUsername = app.GetByUsername(user.Username);

                if (duplicatedUsername != null)
                {
                    return new GeneralJsonResultModel(false, Profile.MsgErrorDupUsername);
                }

                // Guardar usuario
                user.CreatedDate = DateTime.Now;
                user.ModifiedDate = DateTime.Now;
                user.IsActive = false;
                user.PrefersRandom = false;
                user.Role = app.GetRoleById(2); // Usuario con rol normal
                user.ActivationKey = EncryptionHelper.Encrypt(user.Username + DateTime.Now.ToString());
                user.Password = EncryptionHelper.Encrypt(user.Password);
                app.Save(user);

                // Mandar correo al usuario
                string host = HttpContext.Current.Request.Url.Scheme + Uri.SchemeDelimiter + HttpContext.Current.Request.Url.Host + (HttpContext.Current.Request.Url.IsDefaultPort ? "" : ":" + HttpContext.Current.Request.Url.Port);
                string actionLink = String.Format("/Login/Activate/?Username={0}&ActivationKey={1}", user.Username, user.ActivationKey);
                string finalLink = String.Format("{0}{1}", host, actionLink);
                MailerHelper mailHelper = new MailerHelper();
                mailHelper.RegisterUser(user, finalLink).Send();

                // Mandar correo a los administradores
                List<User> admins = (List<User>)app.GetUsersByRoleId(1); // Traer todos los admins
                string actionAdminLink = "/Admin/ActivateUser";
                if (admins != null)
                {
                    string finalAdminLink = String.Format("{0}{1}", host, actionAdminLink);
                    mailHelper.AdminsRegisterUser(admins, user, finalLink).Send();
                }

                return new GeneralJsonResultModel(true, LoginStrings.SentActivationEmail);
            }
            catch
            {
                return new GeneralJsonResultModel(false, LoginStrings.MsgErrorRegister);
            }
        }

        public GeneralJsonResultModel ActivateUser(ActivateUserModel model)
        {
            GeneralJsonResultModel result = new GeneralJsonResultModel();
            UserApplication userApp = new UserApplication();
            User user = userApp.GetByUsername(model.Username);
            if (user != null)
            {
                if (!user.IsActive)
                {
                    if (user.ActivationKey == model.ActivationKey)
                    {
                        user.IsActive = true;
                        userApp.Save(user);

                        return new GeneralJsonResultModel(true, LoginStrings.ActivatedUser);
                    }
                    return new GeneralJsonResultModel(false, LoginStrings.MsgActivatedError);
                }
                return new GeneralJsonResultModel(false, LoginStrings.MsgActiveAlready);
            }
            return new GeneralJsonResultModel(false, LoginStrings.MsgUserInexistant);
        }
        #endregion
    }
}